package com.beerbear.springboottransaction.controller;

import com.beerbear.springboottransaction.service.GoodsStockService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import com.beerbear.springboottransaction.util.Result;

@Controller
@RestController
@Api( tags = "测试事务是否生效")
@RequestMapping("/test/transactionalTest")
@Slf4j
public class GoodsStockController {

    @Autowired
    private GoodsStockService goodsStockService;
    /**
     * create by: Beer Bear
     * description: 第一个方法。
     * create time: 2021/7/25 21:38
     */
    @GetMapping("/exception/first")
    @ApiOperation(value = "关于异常的第一个方法，不能够回滚", notes = "因为异常未能被事务发现，所以没有回滚")
    @ResponseBody
    public Result firstFunctionAboutException(){
        try{
            return goodsStockService.firstFunctionAboutException();
        }catch (Exception e){
            return Result.server_error().Message("操作失败："+e.getMessage());
        }
    }

    @GetMapping("/exception/second")
    @ApiOperation(value = "关于异常的第二个方法，能够回滚", notes = "异常传播到标记了事务注解的方法之外，事务回滚")
    @ResponseBody
    public Result secondFunctionAboutException(){
        try{
            goodsStockService.secondFunctionAboutException();
            return Result.ok();
        }catch (Exception e){
            return Result.server_error().Message("操作失败："+e.getMessage());
        }
    }

    @GetMapping("/exception/third")
    @ApiOperation(value = "关于异常的第三个方法，不能够回滚", notes = "没有抛出合适的异常")
    @ResponseBody
    public Result thirdFunctionAboutException(){
        try{
            goodsStockService.thirdFunctionAboutException();
            return Result.ok();
        }catch (Exception e){
            return Result.server_error().Message("操作失败："+e.getMessage());
        }
    }

    @GetMapping("/exception/third1")
    @ApiOperation(value = "能够回滚", notes = "手动抛出 RuntimeException 抛出合适的异常")
    @ResponseBody
    public Result thirdFunctionAboutException1(){
        try{
            goodsStockService.thirdFunctionAboutException1();
            return Result.ok();
        }catch (Exception e){
            return Result.server_error().Message("操作失败："+e.getMessage());
        }
    }

    @GetMapping("/exception/third2")
    @ApiOperation(value = "能够回滚", notes = "rollbackFor Exception ")
    @ResponseBody
    public Result thirdFunctionAboutException2(){
        try{
            goodsStockService.thirdFunctionAboutException2();
            return Result.ok();
        }catch (Exception e){
            return Result.server_error().Message("操作失败："+e.getMessage());
        }
    }

    @ApiOperation(value = "间接调用private方法，不能够回滚", notes = "因为private方法并不能使事务生效")
    @GetMapping("/usePrivateFunction")
    public Result usePrivateFunction(){
        try{
            goodsStockService.privateFunctionCaller();
            return Result.ok();
        }catch (Exception e){
            return Result.server_error().Message(e.getMessage());
        }
    }

    @ApiOperation(value = "间接调用public方法，不能够回滚", notes = "增强方法必须由代理对象直接调用才生效")
    @GetMapping("/usePublicFunction")
    public Result usePublicFunction(){
        try{
            goodsStockService.privateFunctionCaller();
            return Result.ok();
        }catch (Exception e){
            return Result.server_error().Message(e.getMessage());
        }
    }

    @ApiOperation(value = "AOP中的serviceSelf间接调用public", notes = "能回滚")
    @GetMapping("/usePublicFunctionByAopSelf")
    public Result usePublicFunctionByAopSelf(){
        try{
            goodsStockService.aopSelfCaller();
            return Result.ok();
        }catch (Exception e){
            return Result.server_error().Message(e.getMessage());
        }
    }
}
